package com.framework.utils.JLTran;

import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class RSA256Utils {
	private static final String ENCODING = "UTF-8";  
    private static final String SIGNATURE_ALGORITHM = "SHA256withRSA";  
      
    /** 
     * SHA256WithRSA签名 
     * @param data 
     * @param privateKey 
     * @return 
     * @throws NoSuchAlgorithmException 
     * @throws InvalidKeySpecException 
     * @throws InvalidKeyException 
     * @throws SignatureException 
     * @throws UnsupportedEncodingException 
     */  
    private static byte[] sign256(String data, PrivateKey privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException,   
                                                                             SignatureException, UnsupportedEncodingException {  
          
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);  
             
        signature.initSign(privateKey);  
             
        signature.update(data.getBytes(ENCODING));  
               
        return signature.sign();  
    }  
      
    private static boolean verify256(String data, byte[] sign, PublicKey publicKey){  
        if(data == null || sign == null || publicKey == null){  
            return false;  
        }  
          
        try {  
//        	Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");   
//            cipher.init(Cipher.DECRYPT_MODE, publicKey);
//            
//            System.out.println("签名数据:" + HexStr.parseByte2HexStr(sign));
//            byte[] t = cipher.doFinal(sign);
//            System.out.println("公钥解密:" + HexStr.parseByte2HexStr(t));
//            
//            byte [] indata = data.getBytes("UTF-8");
//            MessageDigest messageDigest;
//            messageDigest = MessageDigest.getInstance("SHA-256");
//            byte[] hash = messageDigest.digest(indata);
//            System.out.println("签名摘要:" + HexStr.parseByte2HexStr(hash));

            
            Signature signetcheck = Signature.getInstance(SIGNATURE_ALGORITHM);  
            signetcheck.initVerify(publicKey);  
            signetcheck.update(data.getBytes("UTF-8"));  
            return signetcheck.verify(sign);  
        } catch (Exception e) {  
            return false;  
        }  
    } 
    /**
     * 256签名
     * @param data
     * @param privateKey
     * @return
     */
    public static String sign256(String data,String privateKey){
    	try{
    		PrivateKey pkey = restorePrivateKey(privateKey);
    		byte[] signDatas = sign256(data, pkey);
    		return new String(Base64.encodeBase64(signDatas));
    	}catch(Exception e){
    		e.printStackTrace();
    	}
    	return null;
    }
    /**
     * 校验256
     * @param data
     * @param publicKeyStr
     * @param sign
     * @return
     */
    public static boolean verify256(String data,String publicKeyStr,String sign){
    	byte[] signed = Base64.decodeBase64(sign.getBytes());
    	PublicKey publicKey = restorePublicKey(publicKeyStr);
    	return verify256(data, signed, publicKey);
    }

    /** 
     * 还原公钥 
     *  
     * @param publickeyStr
     * @return 
     */  
    public static PublicKey restorePublicKey(String publickeyStr) {  
    	byte[] encodedKey = Base64.decodeBase64(publickeyStr.getBytes());  
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(encodedKey);  
        try {  
            KeyFactory factory = KeyFactory.getInstance("RSA");  
            PublicKey publicKey = factory.generatePublic(x509EncodedKeySpec);  
            return publicKey;  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return null;  
    }  
    /** 
     * 还原私钥 
     *  
     * @param privateKey
     * @return 
     */  
    public static PrivateKey restorePrivateKey(String privateKey) {  
    	byte[] encodedKey = Base64.decodeBase64(privateKey.getBytes());  
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(encodedKey);  
        try {  
            KeyFactory factory = KeyFactory.getInstance("RSA");  
            return factory.generatePrivate(pkcs8EncodedKeySpec);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return null;  
    }
}
